use gloo_console::log;
use web_sys::HtmlInputElement;
use yew::{platform::spawn_local, prelude::*};
use yew_router::prelude::*;

use crate::{
  api::rustaceans::{api_rustacean_create, api_rustacean_update, Rustacean},
  components::alert::Alert,
  contexts::CurrentUserContext,
  Route,
};

use super::input::Input;

#[derive(Properties, PartialEq)]
pub struct Props {
  pub rustacean: Option<Rustacean>,
}

#[function_component]
pub fn RustaceanForm(props: &Props) -> Html {
  let name_handle = use_state(|| {
    if let Some(r) = &props.rustacean {
      r.name.clone()
    } else {
      String::default()
    }
  });
  let email_handle = use_state(|| {
    if let Some(r) = &props.rustacean {
      r.email.clone()
    } else {
      String::default()
    }
  });
  let name = (*name_handle).clone();
  let email = (*email_handle).clone();

  let navigator = use_navigator().expect("Navigator not available");
  let current_user_ctx = use_context::<CurrentUserContext>()
    .expect("Current user context is missing");

  let error_message_hander = use_state(String::default);
  let error_message = (*error_message_hander).clone();

  let name_changed = {
    move |e: Event| {
      e.stop_propagation();
      let target = e.target_dyn_into::<HtmlInputElement>();
      if let Some(input) = target {
        name_handle.set(input.value());
      }
      log!("name_changed");
    }
  };
  let email_changed = {
    move |e: Event| {
      e.stop_propagation();
      let target = e.target_dyn_into::<HtmlInputElement>();
      if let Some(input) = target {
        email_handle.set(input.value());
      }
      log!("email_changed");
    }
  };

  let c_name = name.clone();
  let c_email = email.clone();
  let c_rustacean = props.rustacean.clone();

  let onsubmit = {
    move |e: SubmitEvent| {
      e.prevent_default();

      let c_username = c_name.clone();
      let c_email = c_email.clone();
      let c_error_message_hander = error_message_hander.clone();
      let c_navigator = navigator.clone();
      let c_current_user_ctx = current_user_ctx.clone();
      let c_rustacean = c_rustacean.clone();

      match &c_current_user_ctx.token {
        Some(token) => {
          let c_token = token.clone();

          spawn_local(async move {
            if let Some(r) = &c_rustacean {
              match api_rustacean_update(&c_token, r.id, c_username, c_email)
                .await
              {
                Ok(_) => c_navigator.push(&Route::Rustaceans),
                Err(err) => c_error_message_hander.set(err.to_string()),
              };
            } else {
              match api_rustacean_create(&c_token, c_username, c_email).await {
                Ok(_) => c_navigator.push(&Route::Rustaceans),
                Err(err) => c_error_message_hander.set(err.to_string()),
              };
            }
          });
        }
        None => error_message_hander
          .set("Session expired.Please login again.".to_string()),
      }
    }
  };

  html! {
    <form {onsubmit}>
      if error_message.len() > 0 {
        <Alert message={error_message} alert_type="error"/>
      }
      <div>
        <Input
          name="name"
          label="Name"
          input_type="text"
          value={name}
          onchange={name_changed}
        />
      </div>

      <div>
        <Input
          name="email"
          label="E-mail"
          input_type="email"
          value={email}
          onchange={email_changed}
        />
      </div>

      <button type="submit">{"Save"}</button>
    </form>
  }
}
